package com.mall.book.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.mall.book.common.AlipayHelper;
import com.mall.book.entity.po.*;
import com.mall.book.service.*;
import com.mall.book.utils.JwtUtil;
import com.mall.book.wrapper.ResultWrapper;
import com.mall.book.wrapper.StatusWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 订单中心
 * 鉴权：在各方法内部执行
 * 功能：提供对订单的操作支持
 * Created by Dizziness on 2022/3/30 14:26
 */
@RestController
public class OrderCenter {

    @Autowired
    AlipayClient alipayClient;

    @Autowired
    SaleStockService saleStockService;

    @Autowired
    OrderInfoService orderInfoService;

    @Autowired
    OrderStatusService orderStatusService;

    @Autowired
    SubOrderInfoService subOrderInfoService;

    @Autowired
    ExpressAddressService expressAddressService;

    @Autowired
    CartItemService cartItemService;

    @Autowired
    UserBehaviorService userBehaviorService;

    /**
     * 订单生成接口
     * 事务：此处事务不是为订单服务开启的，而是为销售中心维护在售商品信息提供保障
     */
    @PostMapping("/order/genOrders")
    @Transactional
    @ResponseBody
    public ResultWrapper genOrders(HttpServletRequest request) throws InterruptedException {
        String userAccount = JwtUtil.verifyToken(request.getHeader("Authorization"));

// 测试用
// List<HashMap> items = JSON.parseArray(request.getHeader("data"), HashMap.class);

        //商品条目
        List<HashMap> items = JSON.parseArray(request.getParameter("data"), HashMap.class);
        if (items == null || items.isEmpty()) {
            throw new RuntimeException("获取商品列表失败");
        }

        //存储父订单信息
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setUserAccount(userAccount);
        if (!orderInfoService.save(orderInfo)) {
            throw new RuntimeException("订单生成失败!");
        }

        //获取父订单编号
        String fatherId = orderInfo.getOrderId();

// 测试用
// String expressId = request.getHeader("express_id");
        String expressId = request.getParameter("express_id");

        //账单总金额
        float totalAmount = 0;

        //功能：将用户购物车中对应条目删除
        HashMap<String, Object> deleteMap = new HashMap<>();
        deleteMap.put("user_account", userAccount);

        // 开始处理子订单
        for (Map<String, Object> item : items) {
            // 1.取出来
            // 2.查库存余量，不够了就直接返回
            // 3.余量充足尝试拿锁，取不到锁休眠一下重复上述步骤
            SaleStock saleStock = saleStockService.getById((String) item.get("id"));
            Integer quantity = 0;
            int times = 0;
            while (true) {
                // 锁库存之前校验
                quantity = (Integer) item.get("quantity");
                /* 可以在此设计超卖 */
                if (saleStock.getOnSale() < quantity) {
                    throw new RuntimeException("购买数量超过商品库存");
                }
                //尝试锁库存
                saleStock.setOnSale(saleStock.getOnSale() - quantity);
                saleStock.setLocking(saleStock.getLocking() + quantity);
                if (!saleStockService.updateById(saleStock)) {
                    if (times++ >= 20) {
                        throw new RuntimeException("请求超时");
                    }
                    //随机休眠
                    Thread.sleep(new Double(Math.random() * 50).longValue() + 50L);
                    saleStock = saleStockService.getById((String) item.get("id"));
                } else {
                    break;
                }
            }

            //生成子订单信息
            SubOrderInfo subOrderInfo = new SubOrderInfo();
            subOrderInfo.setDeliveryExpressId(expressId);
            subOrderInfo.setFatherId(fatherId);
            subOrderInfo.setBookId((String) item.get("id"));
            subOrderInfo.setBookTitle((String) item.get("title"));
            subOrderInfo.setBookCover((String) item.get("cover"));
            subOrderInfo.setPrice(Float.valueOf(item.get("price") + ""));
            subOrderInfo.setQuantity(quantity);
            float amount = subOrderInfo.getQuantity() * subOrderInfo.getPrice();
            subOrderInfo.setTotalAmount(amount);
            totalAmount += amount;
            //存储子订单信息
            if (!subOrderInfoService.save(subOrderInfo)) {
                throw new RuntimeException("子订单信息存储失败！");
            }

            deleteMap.put("book_id", subOrderInfo.getBookId());
            if (!cartItemService.removeByMap(deleteMap)) {
                throw new RuntimeException("用户购物车条目删除失败！");
            }
        }

        //存储父账单总金额
        orderInfo.setTotalAmount(totalAmount);
        if (!orderInfoService.updateById(orderInfo)) {
            throw new RuntimeException("更新父订单总金额失败！");
        }

        UserBehavior behavior = userBehaviorService.getById(userAccount);
        System.out.println(behavior);
        behavior.setOrders(behavior.getOrders() + items.size());
        if (!userBehaviorService.updateById(behavior)) {
            throw new RuntimeException("更新用户行为失败");
        }

        return ResultWrapper.builder().code(200).msg("订单生成成功！").data(fatherId).build();
    }

    /**
     * 订单支付接口-done
     * 功能：返回document元素，让前端页面提交表单后跳转到alipay进行付款
     */
    @PostMapping("/order/pay")
    @ResponseBody
    public ResultWrapper pay(HttpServletRequest httpRequest) throws AlipayApiException {
        String userAccount = JwtUtil.verifyToken(httpRequest.getHeader("Authorization"));

        String orderId = httpRequest.getParameter("order_id");

        OrderInfo order = orderInfoService.getById(orderId);

        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setNotifyUrl(AlipayHelper.NOTIFY_URL);//通知回调接口
        request.setReturnUrl(AlipayHelper.RETURN_URL);//跳转用户订单页面
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", orderId);//父单号
        bizContent.put("total_amount", order.getTotalAmount());//总金额
        bizContent.put("subject", userAccount);//订单标题使用用户账号进行标注
        bizContent.put("product_code", AlipayHelper.PRODUCT_CODE);
        SimpleDateFormat format = new SimpleDateFormat(AlipayHelper.DATE_PATTERN);
        bizContent.put("time_expire", format.format(System.currentTimeMillis() + 1000 * 60 * 30));//过期时间

        request.setBizContent(bizContent.toString());
        AlipayTradePagePayResponse response = alipayClient.pageExecute(request, "GET");

        return ResultWrapper.builder().code(200).msg("调用成功").data(response.getBody()).build();
    }

    /**
     * 支付成功回调 + 用户支付行为监控
     */
    @PostMapping("/order/notify")
    @Transactional
    @ResponseBody
    public String notify(HttpServletRequest request) {
        //获取支付宝提供的所有回调参数
        Map<String, String[]> parameterMap = request.getParameterMap();

        //查询出父订单信息
        OrderInfo father = orderInfoService.getById(parameterMap.get("out_trade_no")[0]);

        //获取支付单号字段
        String tradeNo = parameterMap.get("trade_no")[0];
        float receipt_amount = Float.valueOf(parameterMap.get("receipt_amount")[0]);

        System.out.println("订单：" + father + "支付成功,支付单号为：" + tradeNo);

        if (tradeNo != null && !"".equals(tradeNo)) {
            //更新父订单的支付单号字段
            father.setTradeNo(tradeNo);
            father.setRecorded(receipt_amount);
            if (!orderInfoService.updateById(father)) {
                throw new RuntimeException("更新订单:" + father.getOrderId()
                        + "\n支付单号:" + tradeNo + "\n实收金额" + receipt_amount + "失败!");
            }

            //获取到所有子订单信息
            HashMap<String, Object> queryMap = new HashMap<>();
            queryMap.put("father_id", father.getOrderId());
            List<SubOrderInfo> subOrderInfos = subOrderInfoService.getByMap(queryMap);

            //循环将子订单状态都设置为待发货
            OrderStatus subStatus = new OrderStatus();
            subStatus.setOrderStatusCode(AlipayHelper.UNSHIPPED);
            for (SubOrderInfo subOrderInfo : subOrderInfos) {
                //先将上锁库存消耗掉
                SaleStock saleStock = saleStockService.getById(subOrderInfo.getBookId());
                saleStock.setLocking(saleStock.getLocking() - subOrderInfo.getQuantity());
                saleStock.setSold(saleStock.getSold() + subOrderInfo.getQuantity());
                if (!saleStockService.updateById(saleStock)) {
                    throw new RuntimeException("更新商品：" + saleStock.getBookId() + "销售库存库存失败！");
                }

                //存储状态信息
                subStatus.setOrderId(subOrderInfo.getSubOrderId());
                if (!orderStatusService.save(subStatus)) {
                    throw new RuntimeException("更新子订单:" + subOrderInfo + "的状态失败:");
                }
            }
            //更新用户行为记录
            UserBehavior behavior = userBehaviorService.getById(father.getUserAccount());
            behavior.setPayment(behavior.getPayment() + subOrderInfos.size());
            if (!userBehaviorService.updateById(behavior)) {
                throw new RuntimeException("更新用户得分失败");
            }
        } else {
            /*此处应该推送到MQ中，提示此次付款通知消息处理失败了，将返回值原样装入包装类塞进MQ，等待处理即可*/
        }

        return "success";//这里是相应给支付宝的，表明这条通知已经被消费了
    }


    /**
     * 取消订单
     * 场景：
     * 父订单的删除一定出现在：1、所有子订单都被删除后；2、支付前。
     * 子订单的删除一定出现在：1、确认收货后；2、退货审核出结果后。
     */
    @PostMapping("/order/delete")
    @Transactional
    @ResponseBody
    public ResultWrapper delete(HttpServletRequest request) {
        JwtUtil.verifyToken(request.getHeader("Authorization"));

        //请求参数是否存在isFather决定了此id是父订单的单号还是子订单单号
        String order_id = request.getParameter("order_id");

        //未支付的父订单被取消或超时
        if ("1".equals(request.getParameter("isFather"))) {
            //获取子订单列表
            HashMap<String, Object> queryMap = new HashMap<>();
            queryMap.put("father_id", order_id);
            List<SubOrderInfo> children = subOrderInfoService.getByMap(queryMap);

            //依次释放子订单上锁库存
            for (SubOrderInfo child : children) {
                String bookId = child.getBookId();
                SaleStock stock = saleStockService.getById(bookId);

                if (stock == null) {
                    throw new RuntimeException("商品" + child + "的在售信息已删除或该商品已下架");
                }

                int quantity = child.getQuantity();
                stock.setLocking(stock.getLocking() - quantity);
                stock.setOnSale(stock.getOnSale() + quantity);

                if (!saleStockService.updateById(stock)) {
                    throw new RuntimeException("订单编号为：" + child.getSubOrderId() + "的订单更新库存失败！");
                }

                if (!subOrderInfoService.removeById(child.getSubOrderId())) {
                    throw new RuntimeException("订单编号为：" + child.getSubOrderId() + "的订单删除失败");
                }
            }

            if (!orderInfoService.removeById(order_id)) {
                throw new RuntimeException("父订单:" + order_id + "删除失败");
            }
        }
        // 父订单已经支付的子订单的删除
        else {
            //子订单的删除
            if (!subOrderInfoService.removeById(order_id)) {
                throw new RuntimeException("子订单:" + order_id + "删除失败");
            }
        }

        return ResultWrapper.builder().code(200).msg("删除成功").build();
    }

    /**
     * 用户级别的订单查询-done
     */
    @PostMapping("/order/getUserOrders")
    @Transactional
    @ResponseBody
    public ResultWrapper getUserOrders(HttpServletRequest request) {
        String account = JwtUtil.verifyToken(request.getHeader("Authorization"));
        //查询出所有父订单信息
        HashMap<String, Object> queryMap = new HashMap<>();
        queryMap.put("user_account", account);
        List<OrderInfo> orderInfos = orderInfoService.getByMap(queryMap);
        queryMap.remove("user_account");

        //最终返回的结果集是一个父订单的集合，父订单内部又是一个子订单的集合
        ArrayList<Map<String, Object>> result = new ArrayList<>();

        SimpleDateFormat formater = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
        //遍历父订单信息
        for (OrderInfo father : orderInfos) {
            //父订单的信息存储在此map中
            Map<String, Object> fatherWrapper = new HashMap<>();

            //父订单号取出来方便下面多次使用
            String tradeNo = father.getTradeNo();
            fatherWrapper.put("trade_no", tradeNo);

            //获取所有子订单信息
            queryMap.put("father_id", father.getOrderId());
            List<SubOrderInfo> childrenInfo = subOrderInfoService.getByMap(queryMap);

            //如果该订单下没有子订单则自动删除该订单
            if (childrenInfo == null || childrenInfo.size() == 0) {
                if (orderInfoService.removeById(father.getOrderId())) {
                    throw new RuntimeException("删除父订单失败");
                }
                continue;
            }

            //如果这个父订单是个未支付的订单，判断是否超时
            if (tradeNo == null || tradeNo.length() == 0) {
                fatherWrapper.remove("trade_no");
                long dead_line = 1800000L + father.getGmtCreate().getTime();
                fatherWrapper.put("dead_line", formater.format(dead_line));//最晚支付时间

                if (dead_line <= System.currentTimeMillis()) {
                    fatherWrapper.put("too_late", true);
                    //释放锁定库存，且恢复在售库存
                    for (SubOrderInfo child : childrenInfo) {
                        String bookId = child.getBookId();
                        SaleStock saleStock = saleStockService.getById(bookId);
                        saleStock.setLocking(saleStock.getLocking() - child.getQuantity());
                        saleStock.setOnSale(saleStock.getOnSale() + child.getQuantity());
                        if (!saleStockService.updateById(saleStock)) {
                            throw new RuntimeException("释放锁定库存失败");
                        }
                    }
                }
            }
            ArrayList<Map<String, Object>> children = new ArrayList<>();
            //循环封装返回值
            for (SubOrderInfo child : childrenInfo) {
                HashMap<String, Object> wrapper = new HashMap<>();
                wrapper.put("sender", null);//寄件人:死信息
                wrapper.put("delivery", null);//收件人
                wrapper.put("id", child.getSubOrderId());//子单号
                wrapper.put("book_id", child.getBookId());//商品编号
                wrapper.put("title", child.getBookTitle());//书名
                wrapper.put("cover", child.getBookCover());//封面
                wrapper.put("price", child.getPrice());//单价
                wrapper.put("quantity", child.getQuantity());//购买数量
                wrapper.put("total_amount", child.getTotalAmount());//订单总价

                children.add(wrapper);
            }
            fatherWrapper.put("id", father.getOrderId());

            fatherWrapper.put("gmt_create", formater.format(father.getGmtCreate()));
            fatherWrapper.put("gmt_modified", formater.format(father.getGmtModified()));
            fatherWrapper.put("children", children);

            result.add(fatherWrapper);
        }
        return ResultWrapper.builder().code(200).msg("查询用户订单成功").data(result).build();
    }

    /**
     * 订单状态查询
     */
    @PostMapping("order/getStatuses")
    @ResponseBody
    public HashMap<String, Object> getOrderStatus(HttpServletRequest request) {
        JwtUtil.verifyToken(request.getHeader("Authorization"));

        String order_id = request.getParameter("order_id");

        //根据订单单号查询出订单状态
        HashMap<String, Object> queryMap = new HashMap<>();
        queryMap.put("order_id", order_id);
        List<OrderStatus> statuses = orderStatusService.getByMap(queryMap);
        queryMap.remove("order_id");

        int current_state = 0;
        for (OrderStatus status : statuses) {
            Integer orderStatusCode = status.getOrderStatusCode();
            current_state = Math.max(current_state, orderStatusCode);
            queryMap.put(orderStatusCode + "", status.getGmtModified());
        }
        //根据订单当前状态分发处理，组装结果集
        ArrayList<StatusWrapper> statusWrappers = new ArrayList<>();
        statusWrappers.add(StatusWrapper.builder().msg("已支付").create_time((Date) queryMap.get("0")).build());

        switch (current_state) {
            case 0:
                statusWrappers.add(StatusWrapper.builder().msg("等待卖家发货").build());
                break;
            case 1:
                statusWrappers.add(StatusWrapper.builder().msg("卖家已发货").create_time((Date) queryMap.get("1")).build());
                statusWrappers.add(StatusWrapper.builder().msg("商品正在等待揽收，请耐心等待").build());
                break;
            case 2:
                statusWrappers.add(StatusWrapper.builder().msg("卖家已发货").create_time((Date) queryMap.get("1")).build());
                statusWrappers.add(StatusWrapper.builder().msg("商品正在运输中，请耐心等待").build());
                break;
            case 3:
                statusWrappers.add(StatusWrapper.builder().msg("商品已送达，请签收").create_time((Date) queryMap.get("3")).build());
                break;
            case 4:
                statusWrappers.add(StatusWrapper.builder().msg("商品已签收").create_time((Date) queryMap.get("4")).build());
                break;
            case 101:
                statusWrappers.add(StatusWrapper.builder().msg("商品已签收").create_time((Date) queryMap.get("4")).build());
                statusWrappers.add(StatusWrapper.builder().msg("申请退款中，请联系商家同意").create_time((Date) queryMap.get("101")).build());
                break;
            case 102:
                statusWrappers.add(StatusWrapper.builder().msg("商品已签收").create_time((Date) queryMap.get("4")).build());
                statusWrappers.add(StatusWrapper.builder().msg("商家已同意退款申请").create_time((Date) queryMap.get("103")).build());
                statusWrappers.add(StatusWrapper.builder().msg("请保证货物完好无损的情况下尽快寄回到商家").build());
                break;
            case 103:
                statusWrappers.add(StatusWrapper.builder().msg("商品已签收").create_time((Date) queryMap.get("4")).build());
                statusWrappers.add(StatusWrapper.builder().msg("商家已同意退款申请").create_time((Date) queryMap.get("103")).build());
                statusWrappers.add(StatusWrapper.builder().msg("货物正在运输中，请等待商家收货").build());
                break;
            case 104:
                statusWrappers.add(StatusWrapper.builder().msg("商品已签收").create_time((Date) queryMap.get("4")).build());
                statusWrappers.add(StatusWrapper.builder().msg("商家已同意退款申请").create_time((Date) queryMap.get("103")).build());
                statusWrappers.add(StatusWrapper.builder().msg("货物已送达，请等待卖家签收").build());
                break;
            case 105:
                statusWrappers.add(StatusWrapper.builder().msg("商品已签收").create_time((Date) queryMap.get("4")).build());
                statusWrappers.add(StatusWrapper.builder().msg("商家已同意退款申请").create_time((Date) queryMap.get("103")).build());
                statusWrappers.add(StatusWrapper.builder().msg("商家已收货，请等待商家审核是否满足退款标准").build());
                break;
            case 106:
                statusWrappers.add(StatusWrapper.builder().msg("商品已签收").create_time((Date) queryMap.get("4")).build());
                statusWrappers.add(StatusWrapper.builder().msg("商家拒绝退款").build());
                break;
            case 107:
                statusWrappers.add(StatusWrapper.builder().msg("商品已签收").create_time((Date) queryMap.get("4")).build());
                statusWrappers.add(StatusWrapper.builder().msg("商家同意退款，请留意支付渠道的账单信息").create_time((Date) queryMap.get("107")).build());
                break;
            case 108:
                statusWrappers.add(StatusWrapper.builder().msg("商品已签收").create_time((Date) queryMap.get("4")).build());
                statusWrappers.add(StatusWrapper.builder().msg("退款成功").create_time((Date) queryMap.get("108")).build());
                break;
            case 998:
                statusWrappers.add(StatusWrapper.builder().msg("订单已完成").create_time((Date) queryMap.get("4")).build());
                break;
        }

        HashMap<String, Object> result = new HashMap<>();
        result.put("current_state", current_state);
        result.put("statuses", statusWrappers);

        return result;
    }

    /**
     * 通知商家发货接口
     * 功能：将发货通知推送到MQ中，供商家去消费通知
     */
    @PostMapping("order/shipment")
    @Transactional
    @ResponseBody
    public ResultWrapper shipment(HttpServletRequest request) {
        JwtUtil.verifyToken(request.getHeader("Authorization"));

        String order_id = request.getParameter("order_id");

        OrderStatus status = new OrderStatus();
        status.setOrderId(order_id);
        //设置已出库待揽收
        status.setOrderStatusCode(AlipayHelper.SHIPPED);
        if (!orderStatusService.save(status)) {
            throw new RuntimeException("更新已出库状态失败");
        }
        //设置已揽收
        status.setOrderStatusCode(AlipayHelper.UNDELIVERED);
        if (!orderStatusService.save(status)) {
            throw new RuntimeException("更新已揽收状态失败");
        }

        return ResultWrapper.builder().code(200).build();
    }

    /**
     * 用户确认收货接口
     * 功能：更新对应订单的收货状态
     */
    @PostMapping("/order/receipt")
    @Transactional
    @ResponseBody
    public ResultWrapper receipt(HttpServletRequest request) {
        String user_account = JwtUtil.verifyToken(request.getHeader("Authorization"));

        OrderStatus status = new OrderStatus();
        status.setOrderId(request.getParameter("order_id"));
        status.setOrderStatusCode(4);
        if (!orderStatusService.save(status)) {
            throw new RuntimeException("确认收货失败！");
        }

        UserBehavior behavior = userBehaviorService.getById(user_account);
        behavior.setScore(behavior.getScore() + 10);
        if (!userBehaviorService.updateById(behavior)) {
            throw new RuntimeException("更新用户行为失败");
        }

        return ResultWrapper.builder().code(200).build();
    }

    /**
     * 退款接口 + 用户行为监控
     * 功能：推送退款申请给商家
     * 测试功能：8成概率同意退款，然后一口气走完退货流程，接着8成概率退款成功，2成不给退
     */
    @PostMapping("/order/refund")
    @Transactional
    @ResponseBody
    public ResultWrapper refund(HttpServletRequest request) throws AlipayApiException {
        String user_account = JwtUtil.verifyToken(request.getHeader("Authorization"));

        UserBehavior behavior = userBehaviorService.getById(user_account);
        behavior.setRefund(behavior.getRefund() + 1);
        behavior.setScore(behavior.getScore() - 10);
        if (!userBehaviorService.updateById(behavior)) {
            throw new RuntimeException("更新用户行为失败");
        }

        OrderStatus status = new OrderStatus();
        String sub_id = request.getParameter("order_id");
        status.setOrderId(sub_id);

        //拒绝退款
        if (!getFlag()) {
            status.setOrderStatusCode(AlipayHelper.REFUND_REFUSE);
            if (!orderStatusService.save(status)) {
                throw new RuntimeException("更新订单状态失败");
            }
            return ResultWrapper.builder().code(200).msg("退款失败：商家拒绝退款").build();
        }
        //更新一波状态，模拟买家退货流程
        status.setOrderStatusCode(AlipayHelper.REFUND_UNSHIPPED);
        if (!orderStatusService.save(status)) {
            throw new RuntimeException("更新订单状态REFUND_UNSHIPPED失败");
        }

        status.setOrderStatusCode(AlipayHelper.REFUND_SHIPPED);
        if (!orderStatusService.save(status)) {
            throw new RuntimeException("更新订单状态REFUND_SHIPPED失败");
        }

        status.setOrderStatusCode(AlipayHelper.REFUND_UNDELIVERED);
        if (!orderStatusService.save(status)) {
            throw new RuntimeException("更新订单状态REFUND_UNDELIVERED失败");
        }

        status.setOrderStatusCode(AlipayHelper.REFUND_DELIVERED);
        if (!orderStatusService.save(status)) {
            throw new RuntimeException("更新订单状态REFUND_DELIVERED失败");
        }

        //卖家觉得商品无法二次出售，审核未通过
        if (!getFlag()) {
            status.setOrderStatusCode(AlipayHelper.REFUND_REFUSE);
            if (!orderStatusService.save(status)) {
                throw new RuntimeException("更新订单状态REFUND_REFUSE失败");
            }
            return ResultWrapper.builder().code(200).msg("退款失败：商品破损，无法二次销售").build();
        }
        //同意退款
        status.setOrderStatusCode(AlipayHelper.REFUND_ACCEPT);
        if (!orderStatusService.save(status)) {
            throw new RuntimeException("更新订单状态REFUND_ACCEPT失败");
        }

        /*退款流程-start*/
        SubOrderInfo sub_order = subOrderInfoService.getById(sub_id);
        OrderInfo father_order = orderInfoService.getById(sub_order.getFatherId());

        AlipayTradeRefundRequest refundRequest = new AlipayTradeRefundRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", father_order.getOrderId());
        bizContent.put("trade_no", father_order.getTradeNo());
        bizContent.put("out_request_no", sub_order.getSubOrderId());
        bizContent.put("refund_amount", sub_order.getTotalAmount());//退款金额

        refundRequest.setBizContent(bizContent.toString());
        AlipayTradeRefundResponse response = alipayClient.execute(refundRequest);

        if (!"10000".equals(response.getCode())) {
            throw new RuntimeException("第三方支付宝拒绝退款！" + response.getCode());
        }

        status.setOrderStatusCode(AlipayHelper.REFUND_SUCCESS);
        if (!orderStatusService.save(status)) {
            throw new RuntimeException("更新订单状态REFUND_SUCCESS失败");
        }

        father_order.setRecorded(father_order.getRecorded() - sub_order.getTotalAmount());
        if (!orderInfoService.updateById(father_order)) {
            throw new RuntimeException("扣减父订单入账金额失败");
        }

        return ResultWrapper.builder().code(200).msg("卖家已同意退款，但账单金额可能延迟到账，请耐心等待...").build();
    }

    /**
     * 退款接口专用辅助方法
     * 功能：80% => true，20% => false
     */
    private boolean getFlag() {

        int flag = 15;
        while (flag == 15) {
            flag = 0;
            //16种情况: [0,11]->true,[12-14]->false,[15]->roll_again
            for (int i = 0; i < 4; i++) {
                flag <<= 1;
                if ((Math.random() * 1000) > 500) {
                    flag += 1;
                }
            }
        }
        return flag < 12;
    }
}
